package io.jplus.admin.service.impl;

import com.jfinal.aop.Inject;
import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Page;
import io.jboot.aop.annotation.Bean;
import io.jboot.components.cache.annotation.Cacheable;
import io.jboot.components.rpc.annotation.RPCBean;
import io.jboot.db.model.Column;
import io.jboot.db.model.Columns;
import io.jboot.service.JbootServiceBase;
import io.jplus.JplusConsts;
import io.jplus.admin.model.Dept;
import io.jplus.admin.model.User;
import io.jplus.admin.model.UserRole;
import io.jplus.admin.service.DeptService;
import io.jplus.admin.service.UserRoleService;
import io.jplus.admin.service.UserService;
import io.jplus.common.Query;
import io.jplus.utils.EncryptUtils;

import java.util.ArrayList;
import java.util.List;


@Bean
@RPCBean
public class UserServiceImpl extends JbootServiceBase<User> implements UserService {

    @Inject
    DeptService deptService;

    @Inject
    UserRoleService userRoleService;

    @Override
    public Ret doLogin(String userName, String password) {
        String errMsg = "用户名或密码错误";
        User user = findByUserName(userName);
        if (user == null) {
            return Ret.fail(JplusConsts.RET_MSG, errMsg);
        }
        String enpwd = EncryptUtils.encryptPassword(password, user.getSalt());
        if (!enpwd.equals(user.getPassword())) {
            return Ret.fail(JplusConsts.RET_MSG, errMsg);
        }
        return Ret.ok("user", user);
    }

    @Override
    @Cacheable(name = "user", key = "#(userName)")
    public User findByUserName(String userName) {
        return DAO.findFirstByColumn(Column.create("username", userName));
    }

    @Override
    public Page<User> queryPage(Query query) {
        Columns columns = Columns.create();
        Page<User> page = DAO.paginateByColumns(query.getCurrPage(), query.getLimit(), columns, query.getOrderBy());
        for (User user : page.getList()) {
            if (user.getDeptId() == null) {
                continue;
            }
            Dept dept = deptService.findById(user.getDeptId());
            if (dept != null) {
                user.setDeptName(dept.getName());
            }
        }
        return page;
    }

    @Override
    public List<User> queryList(Query query) {
        Columns columns = Columns.create();

        return DAO.findListByColumns(columns);
    }

    @Override
    public boolean saveUser(User user) {
        String pwd = user.getPassword();
        if (StrKit.isBlank(pwd)) {
            pwd = "111111";
        }
        String salt = EncryptUtils.generateSalt(20);
        user.setSalt(salt);
        user.setPassword(EncryptUtils.encryptPassword(pwd, salt));
        boolean tag = save(user)==null?false:true;
        if (tag) {
            List<String> roleIdList = user.getRoleIdList();
            if (roleIdList == null) {
                roleIdList = user.get("role_id_list");
            }
            //can use batchsave
            for (Object roleId : roleIdList) {
                userRoleService.save(new UserRole(roleId, user.getId()));
            }
        }
        return tag;
    }

    @Override
    public boolean updateUser(User user) {
        String pwd = user.getPassword();
        if (StrKit.notBlank(pwd)) {
            String salt = EncryptUtils.generateSalt(20);
            user.setSalt(salt);
            user.setPassword(EncryptUtils.encryptPassword(pwd, salt));
        }
        List<String> roleIdList = user.getRoleIdList();
        if (roleIdList == null) {
            roleIdList = user.get("role_id_list");
        }
        boolean tag = update(user);
        if (tag) {
            userRoleService.deleteByUserId(user.getId());
            for (String roleId : roleIdList) {
                userRoleService.save(new UserRole(user.getId(), roleId));
            }
        }
        return tag;
    }

    @Override
    public User findUserById(Object id) {
        User user = findById(id);
        Dept dept = deptService.findById(user.getDeptId());
        if (dept != null) {
            user.setDeptName(dept.getName());
        }
        List<UserRole> userRoleList = userRoleService.findListByUserId(user.getId());
        List<String> roleIdList = new ArrayList<>(userRoleList.size());
        for (UserRole userRole : userRoleList) {
            roleIdList.add(userRole.getRoleId());
        }
        user.setRoleIdList(roleIdList);
        return user;
    }

    @Override
    public boolean deleteById(Object... ids) {
        boolean tag = false;
        for (Object id : ids) {
            tag = DAO.deleteById(id);
        }
        return tag;
    }
}